﻿#include "map_playermgr.h"
#include "ManagerHelper.h"
#include "../share/MessageDef.h"
//#include "script_define.h"
//#include "Map.h"
#include "../share/GameHostManager.h"
#include "../share/proxyclient_service.h"
#include "mapobj_manager.h"
//#include "MapSlot.h"
#include "../share/sql/mysql_connection.h"
#include "../share/sql/mysql_resultset.h"
#include "../share/time_module.h"
#include "MapServer.h"
//#include "PlayerDataStruct.inl"

void CMapPlayerManger::Initialize()
{
	player_id_map_.clear();
	socket_id_map_.clear();
	m_pid2mapid.clear();
	player_destroy_.clear();
	m_pid2playerInfo.clear();

	//	初始化数据
// 	uint32_t mapId = GameHostManager::GetInstance().GetMapId();
// 	if (MapSlot::GetInstance().GetLuaManagerPtr() != NULL)
// 	{
// 		MapSlot::GetInstance().GetLuaManagerPtr()->RunScriptFunction(LUA_WebRedisScript, LUA_InitPlayerManagerData, mapId);
// 	}
}

Player* CMapPlayerManger::GetPlayerByPlayerID(int playerId)
{
	TObjIDMap::iterator iter = player_id_map_.find(playerId);
	if (iter == player_id_map_.end())
	{
		return NULL;
	}
	return GetPlayerByObjID(iter->second);
}

Player* CMapPlayerManger::GetPlayerByObjID(OBJ_ID_TYPE obj_id)
{
	return CMAPObjManager::GetInstance().GetObjectByID< Player >(obj_id);
}

Player* CMapPlayerManger::GetPlayerBySocket(int socket)
{
	TObjIDMap::iterator it = socket_id_map_.find(socket);
	if (it == socket_id_map_.end())
	{
		return NULL;
	}

	return GetPlayerByObjID(it->second);
}

int CMapPlayerManger::PlayerEnterGame(Player& player)
{
	std::pair< TObjIDMap::iterator, bool > insert_pair = player_id_map_.insert(TObjIDMap::value_type(player.GetPlayerId(), player.get_id()));
	if (insert_pair.second == false)
	{
		LOG_ERROR("default","insert player %d %d %d into role_map faild", player.GetAccount(), player.GetPlayerId(), player.get_id());
		return ::common::ERR_UNKNOWN;
	}

	return ::common::SUCCEED;
}

int CMapPlayerManger::RegistePlayerSocket(int32_t fd_, int obj_id)
{
	std::pair< TObjIDMap::iterator, bool > insert_pair = socket_id_map_.insert(TObjIDMap::value_type(fd_, obj_id));
	if (insert_pair.second == false)
	{
		LOG_ERROR("default","insert  socket %d obj %d into map faild", fd_, obj_id);
	}

	return -1;
}

int CMapPlayerManger::UnRegistePlayerSocket(int32_t fd_)
{
	TObjIDMap::iterator iter = socket_id_map_.find(fd_);
	if (iter != socket_id_map_.end())
	{
		socket_id_map_.erase(iter);
	}
	return 0;
}

void CMapPlayerManger::SetPlayerId2MidMap(uint32_t playerId, uint32_t mapid)
{
	m_pid2mapid[playerId] = mapid;
}

int32_t CMapPlayerManger::GetMapIdByPlayerId(int32_t playerId)
{
	TPlayerIDMapIDMap::iterator it = m_pid2mapid.find(playerId);
	if (it != m_pid2mapid.end())
	{
		return it->second;
	}
	return 0;
}


int CMapPlayerManger::PlayerLeaveGame(Player& player)
{
	LOG_INFO("default","Player %d %d %d Leave Scene, reason %d", player.GetAccount(), player.GetPlayerId(), player.get_id());

	if (player.GetSocketId() > 0)
	{
		CloseTcpConnect(player.GetSocketId());
	}
	player.SetSocketId(0);

	//从管理中移除这个实体;
	AddPlayerDestroy(player);

	return ::common::SUCCEED;
}

void CMapPlayerManger::CloseTcpConnect(int32_t fd)
{
	TObjIDMap::iterator it = socket_id_map_.find(fd);
	if (it != socket_id_map_.end())
	{
		socket_id_map_.erase(it);
	}

	// 关闭与客户端的连接
	//MapServer::GetInstance().client_close_socket(fd);
}

void CMapPlayerManger::OnPlayerDisconnect(int32_t fd)
{
	//玩家掉线，先不删掉玩家，只是将玩家的连接断开，过10分钟后才删除玩家实体
	Player* player = GetPlayerBySocket(fd);
	if ( player == NULL )
	{
		LOG_INFO("default","client diconnect cant find player fd[%d]", fd);
		return;
	}
	
	//从管理中移除这个实体;
	AddPlayerDestroy(*player);

	LOG_INFO("default","player[%d] is disconnect!", player->GetPlayerId());

	return;
}

void CMapPlayerManger::AddPlayerDestroy(Player& player)
{
	TObjIDMap::iterator it = player_id_map_.find(player.GetPlayerId());
	if (it != player_id_map_.end())
	{
		player_id_map_.erase(it);
	}
	player_destroy_.push_back(player.get_id());
}

void CMapPlayerManger::PlayerDestroyDoing()
{
	TPlayerDestroyVector::iterator it = player_destroy_.begin();
	for (; it != player_destroy_.end(); ++it )
	{
		OBJ_ID_TYPE obj_id = *it;
		Player* player = CMAPObjManager::GetInstance().GetObjectByID< Player >(obj_id);
		if (player != NULL)
		{
			CMAPObjManager::GetInstance().DestoryObject(*it);
		}
	}

	player_destroy_.clear();
}

void CMapPlayerManger::UpdateLoginPlayerInfo(std::string& playerInfo)
{
	Json::Value jm;
	jm.clear();
	JsonReader(playerInfo, jm);
	uint32_t playerId = jm["playerId"].asUInt();
	
	m_pid2playerInfo[playerId] = playerInfo;
}

std::string CMapPlayerManger::GetLoginPlayerInfo(uint32_t playerId)
{
	std::string strInfo = "";
	auto _it = m_pid2playerInfo.find(playerId);
	if (_it != m_pid2playerInfo.end())
	{
		strInfo = _it->second;
		m_pid2playerInfo.erase(playerId);
	}

	return strInfo;
}

void CMapPlayerManger::TickUpdate()
{
	uint64_t _now_time = CUR_MS;
	if (m_last_updateCount_time == 0 || _now_time - m_last_updateCount_time > update_palyercount_time)
	{
		m_last_updateCount_time = _now_time;
		UpdatePlayerCountToWebRedis();
	}

	CMapPlayerManger::GetInstance().PlayerDestroyDoing();
}

void CMapPlayerManger::UpdatePlayerCountToWebRedis()
{
	int32_t online = GetOnlineCount();
	if (online == m_last_playerCount)
	{
		return;
	}
	m_last_playerCount = online;


// 	uint32_t mapid = GameHostManager::GetInstance().GetMapId();
// 	if (MapSlot::GetInstance().GetLuaManagerPtr() != NULL)
// 	{
// 		MapSlot::GetInstance().GetLuaManagerPtr()->RunScriptFunction(LUA_WebRedisScript, LUA_UpdatePlayerCount, mapid, online);
// 	}
}

void CMapPlayerManger::OnPlayerEnterScene(int32_t playerid)
{
	Player* _player = GetPlayerByPlayerID(playerid);
	if (nullptr == _player)
	{
		return;
	}

	// 保存老的可视组和场景ID
	uint32_t _last_viewgroup_id = 0;

	// 设置新的可视组和场景ID
// 	_player->SetViewGroup(_last_viewgroup_id);
// 	_player->ClearLastViewGroup();
// 
// 	uint32_t _scene_id = _player->GetSceneId();
// 	double _pos_x = _player->GetPosX();
// 	double _pos_y = _player->GetPosY();
// 	double _pos_z = _player->GetPosZ();
// 
// 	_player->Send2CEnterScene(_scene_id, _pos_x, _pos_y, _pos_z);
}

Player* CMapPlayerManger::GetPlayerByClientKey(uint64_t client_key)
{
	uint32_t player_id = client_key - player_key_start;
	//Player* player = CGameObjManager::GetInstance().GetObjectByID<Player*>(player_id);
	Player *player = CMapPlayerManger::GetInstance().GetPlayerByPlayerID(player_id);
	return player;
}